#pragma once
#include "ZuiLib.h"
#include "LRefObject.h"
#include "support/filedlgs/tinyfiledialogs.h"

#ifdef CreateDirectory
#undef CreateDirectory
#endif

namespace ZuiLib {

class LFileUtils :public LRefObject<ZFileUtils>
{
public:
	static this_t* instance()
	{
		return ZFileUtils::Instance();
	}

	int getFileData(LuaFuncState& L)
	{
		ZRefCountedPtr<ZFileData> data = pThis->GetFileData(L.arg(0).toString());
		if (data)
			return L.lreturn(L.newString((char*)data->data(), data->size()));
		else
			return 0;
	}

	int setSearchPath(LuaFuncState& L)
	{
		pThis->SetSearchPath(L.arg(0).toString());
		return 0;
	}

	int getPathFromName(LuaFuncState& L)
	{
		return L.lreturn(pThis->GetPathFromName(L.arg(0).toString()));
	}

	int getWorkPath(LuaFuncState& L)
	{
		return L.lreturn(pThis->GetWorkPath());
	}

	int getInstancePath(LuaFuncState& L)
	{
		return L.lreturn(pThis->GetInstancePath());
	}

	int isGlobalPath(LuaFuncState& L)
	{
		return L.lreturn(pThis->IsGlobalPath(L.arg(0).toString()));
	}

	int getFileSize(LuaFuncState& L)
	{
		return L.lreturn((long)pThis->GetFileSize(L.arg(0).toString()));
	}

	int isFileExist(LuaFuncState& L)
	{
		return L.lreturn(pThis->IsFileExist(L.arg(0).toString()));
	}

	int isDirectoryExist(LuaFuncState& L)
	{
		return L.lreturn(pThis->IsDirectoryExist(L.arg(0).toString()));
	}

	int removeFile(LuaFuncState& L)
	{
		return L.lreturn(pThis->RemoveFile(L.arg(0).toString()));
	}

	int renameFile(LuaFuncState& L)
	{
		return L.lreturn(pThis->RenameFile(L.arg(0).toString(), L.arg(1).toString()));
	}

	int createDirectory(LuaFuncState& L)
	{
		return L.lreturn(pThis->CreateDirectory(L.arg(0).toString()));
	}


    //title,pattern,defaultPath,description
    int openSingleFileDialog(LuaFuncState& L)
    {
        const char* title = L.arg(0).toString();

        size_t patternLen = 0;
        const char* patternStr = L.arg(1).toString(&patternLen);
        const char* defaultPath = L.arg(2).toString();
        const char* description = L.arg(3).toString();

        std::vector<const char*> patterns;
        patterns.push_back(patternStr);
        for(size_t i=0;i<patternLen;++i)
        {
            if(!patternStr[i])
                patterns.push_back(patternStr + i);
       }

        const char* files = tinyfd_openFileDialog(title, defaultPath,
            0,patterns.data(), description,0);
        if (files)
            return L.lreturn(files);
        else
            return 0;
    }

    //title,pattern,defaultPath,description
    int openMultiFileDialog(LuaFuncState& L)
    {
        const char* title = L.arg(0).toString();

        size_t patternLen = 0;
        const char* patternStr = L.arg(1).toString(&patternLen);
        const char* defaultPath = L.arg(2).toString();
        const char* description = L.arg(3).toString();

        std::vector<const char*> patterns;
        patterns.push_back(patternStr);
        for (size_t i = 0; i<patternLen; ++i)
        {
            if (!patternStr[i])
                patterns.push_back(patternStr + i);
        }
        const char* files = tinyfd_openFileDialog(title, defaultPath, 0,
            patterns.data(), description, 1);

        if (files)
            return L.lreturn(files);
        else
            return 0;
    }

    int openFolderDialog(LuaFuncState& L)
    {
        const char* title = L.arg(0).toString();
        const char* defaultPath = L.arg(1).toString();
        const char* files = tinyfd_selectFolderDialog(title, defaultPath);
        if (files)
            return L.lreturn(files);
        else
            return 0;
    }


	BEGIN_MAP_FUNC(LFileUtils)
	DECLARE_FUNC(getFileData),
	DECLARE_FUNC(setSearchPath),
	DECLARE_FUNC(getPathFromName),
	DECLARE_FUNC(getWorkPath),
	DECLARE_FUNC(getInstancePath),
	DECLARE_FUNC(isGlobalPath),
	DECLARE_FUNC(getFileSize),
	DECLARE_FUNC(isFileExist),
	DECLARE_FUNC(isDirectoryExist),
	DECLARE_FUNC(removeFile),
	DECLARE_FUNC(renameFile),
	DECLARE_FUNC(createDirectory),
    DECLARE_FUNC(openSingleFileDialog),
    DECLARE_FUNC(openMultiFileDialog),
    DECLARE_FUNC(openFolderDialog),
	END_MAP_FUNC
};

}//namespace
